﻿using System;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using CompactMapper.Orm.Annotations;
using CompactMapper.Orm.Contracts;
using CompactMapper.Orm.UnitOfWork.Mappings;
using System.Collections.Generic;

namespace CompactMapper.Orm.Tests
{
    [TestClass]
    public class HasAndBelongsToManyRelationDeleteCascadeTests : OrmInMemoryTest
    {
        [Table]
        public class HasAndBelongsToManyParent : IKeyedPersistent
        {
            private readonly List<HasAndBelongsToManyDescendant> _HasAndBelongsToManyDescendants = new List<HasAndBelongsToManyDescendant>();

            [GuidPrimaryKey]
            public IKey Key { get; set; }

            [HasAndBelongsToMany]
            public IEnumerable<HasAndBelongsToManyDescendant> HasAndBelongsToManyDescendants
            {
                get
                {
                    return _HasAndBelongsToManyDescendants;
                }
            }

            public void AddHasAndBelongsToManyDescendant(HasAndBelongsToManyDescendant HasAndBelongsToManyDescendant)
            {
                _HasAndBelongsToManyDescendants.Add(HasAndBelongsToManyDescendant);
            }

            public HasAndBelongsToManyParent()
            {
                Key = AbstractKeyFactory.For<Guid>().New();
            }
        }

        [Table]
        public class HasAndBelongsToManyDescendant : IKeyedPersistent
        {
            [GuidPrimaryKey]
            public IKey Key { get; set; }

            public HasAndBelongsToManyDescendant()
            {
                Key = AbstractKeyFactory.For<Guid>().New();
            }
        }

        [TestMethod]
        public void HasAndBelongsToManyRelation_DeleteCascades()
        {
            var parent = new HasAndBelongsToManyParent();
            parent.AddHasAndBelongsToManyDescendant(new HasAndBelongsToManyDescendant());
            using (var unitOfWork = GetKeyedUnitOfWork<HasAndBelongsToManyParent>())
            {
                unitOfWork.MakePersistent(parent);
            }
            using (var unitOfWork = GetKeyedUnitOfWork<HasAndBelongsToManyParent>())
            {
                unitOfWork.Delete(parent.Key);
            }
            using (var unitOfWork = GetKeyedUnitOfWork<HasAndBelongsToManyParent>())
            {
                Assert.IsFalse(unitOfWork.GetAll().Any(), "Parent wasn't deleted");
            }
            using (var unitOfWork = GetKeyedUnitOfWork<HasAndBelongsToManyDescendant>())
            {
                Assert.IsFalse(unitOfWork.GetAll().Any(), "Descendant wasn't deleted");
            }
        }
    }
}
